package com.google.code.jholidays.events;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.util.Calendar;

import org.junit.Test;

import com.google.code.jholidays.core.EventDescriptor;

public class FixedEventFactoryTest {

    @Test
    public void testMatchesGoodExpressionOneDate() {
	EventDescriptor descriptor = new EventDescriptor(1);
	FixedEventFactory factory = new FixedEventFactory();

	descriptor.setExpression("01.01");
	assertTrue(factory.matches(descriptor));

	descriptor.setExpression("1.01");
	assertTrue(factory.matches(descriptor));

	descriptor.setExpression("01.1");
	assertTrue(factory.matches(descriptor));

	descriptor.setExpression("1.1");
	assertTrue(factory.matches(descriptor));
    }

    @Test
    public void testMatchesMany() {
	Calendar calendar = Calendar.getInstance();
	EventDescriptor descriptor = new EventDescriptor(1);
	FixedEventFactory factory = new FixedEventFactory();

	int minDate = calendar.getActualMinimum(Calendar.DAY_OF_YEAR);

	int maxDate = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);

	int minYear = calendar.getActualMinimum(Calendar.YEAR);
	int maxYear = calendar.getActualMaximum(Calendar.YEAR);
	System.out.println(minYear);
	System.out.println(maxYear);

	for (int i = minDate; i <= maxDate; ++i) {
	    calendar.set(Calendar.DAY_OF_YEAR, i);

	    StringBuilder sb = new StringBuilder();
	    sb.append(calendar.get(Calendar.DATE));
	    sb.append('.');
	    sb.append(calendar.get(Calendar.MONTH) + 1);

	    descriptor.setExpression(sb.toString());
	    assertTrue(factory.matches(descriptor));

	}
    }

    @Test
    public void testDoesntMatchMalformedExpression() {
	EventDescriptor descriptor = new EventDescriptor(1);
	FixedEventFactory factory = new FixedEventFactory();

	descriptor.setExpression("a01.01");
	assertFalse(factory.matches(descriptor));

	descriptor.setExpression("01a.01");
	assertFalse(factory.matches(descriptor));

	descriptor.setExpression("01.a01");
	assertFalse(factory.matches(descriptor));

	descriptor.setExpression("01.01a");
	assertFalse(factory.matches(descriptor));

	descriptor.setExpression("01:01");
	assertFalse(factory.matches(descriptor));

	descriptor.setExpression("01-01");
	assertFalse(factory.matches(descriptor));

	descriptor.setExpression("aaa");
	assertFalse(factory.matches(descriptor));
    }

    @Test
    public void testNullDescriptorDoesntMatch() {
	FixedEventFactory factory = new FixedEventFactory();
	assertFalse(factory.matches(null));
    }

    @Test
    public void testAnalizeValidExpression() {
	EventDescriptor descriptor = new EventDescriptor(1);
	descriptor.setName("event");
	descriptor.setDescription("none");
	descriptor.setExpression("1.01");

	FixedEventFactory factory = new FixedEventFactory();

	IEvent event = factory.analizeExpression(descriptor, null);
	assertNotNull(event);
	assertTrue(event instanceof FixedEvent);

	// compare descriptors
	assertSame(descriptor, event.getDescriptor());
    }

    @Test
    public void testAnalizeInvalidExpression() {
	EventDescriptor descriptor = new EventDescriptor(1);
	descriptor.setName("event");
	descriptor.setDescription("none");
	descriptor.setExpression("aaa");

	FixedEventFactory factory = new FixedEventFactory();

	IEvent event = factory.analizeExpression(descriptor, null);
	assertNull(event);
    }

}
